package com.itcast.utils;


import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

public class JDBCUtils {
    private static Properties properties = new Properties();

    static {
        //1.注册驱动
        try {
            // 加载配置文件，使用当前类的类加载器
            //getResourceAsStream()返回用于读取指定资源的输入流。
            //load()从输入字节流中读取属性列表（键和元素对）。
            properties.load(ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"));
            //getProperty()在此属性列表中搜索具有指定键的属性。
            Class.forName(properties.getProperty("driverClassName"));

        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    public static int executeUpdate(String sql, Object... args) throws SQLException, ClassNotFoundException {
        //使用JDBC操作数据库
        //2.获取链接
        Connection connection = getConnection();
        //3.获取执行者对象
        PreparedStatement statement = connection.prepareStatement(sql);
        for (int i = 0; i < args.length; i++) {
            statement.setObject(i + 1, args[i]);
        }
        //4.告诉他sql语句去执行去 ,executeUpdate 本质执行DML语句
        int row = statement.executeUpdate();

        //5.释放资源
        close(statement, connection);
        return row;
    }

    public static <T> List<T> executeQuery(String sql, Class<T> clazz, Object... args) throws Exception {

        //2.获取链接
        Connection connection = getConnection();
        //获取执行者对象
        PreparedStatement statement = connection.prepareStatement(sql);
//        for (int i = 0; i < args.length; i++) {
//            statement.setObject(i + 1, args[i]);
//        }
        //执行sql语句
        ResultSet rs = statement.executeQuery();
        //遍历结果集
        /*
            ResultSet
                next(); 将游标往下移动一行,并且返回改行是否有数据
                getXxx(String columnName); 根据列名获取列值
         */
        Field[] fields = clazz.getDeclaredFields();
        List<T> list = new ArrayList<>();
        while (rs.next()) {
            T t = clazz.getConstructor().newInstance();
            for (Field field : fields) {
                field.setAccessible(true);
                String name = field.getName();
                Object value = rs.getObject(name);
                field.set(t, value != null ? value.toString() : null);
            }
            list.add(t);
        }
        //释放资源
        close(statement, connection, rs);
        return list;
    }

    private static Connection getConnection() throws SQLException {
        //使用JDBC操作数据库
        //2.获取链接
        Connection connection = DriverManager.getConnection(properties.getProperty("url"), properties.getProperty("username"), properties.getProperty("password"));
        return connection;
    }


    public static void close(Statement state, Connection conn) {

        close(state, conn, null);
    }

    public static void close(Statement state, Connection conn, ResultSet rs) {
        try {
            if (rs != null) rs.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        try {
            if (state != null) state.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        try {
            if (conn != null) conn.close();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
